#include <tmc/cmem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"

#define LINE_LENGTH 1600
#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )

int parse(char *filename, int ***connections_array, int **numconn_array, int *num_nodes) {
  FILE *file;
  int n;
  char c;

  file = fopen(filename, "r");

  // Count the number of lines
  n = 0;
  while((c = fgetc(file)) != EOF) {
    if (c == '\n') {
      n++;
    }
  }
  *num_nodes = n;

  // Allocate some space.
  *connections_array = tmc_cmem_malloc(sizeof(int *) * n);
  *numconn_array = tmc_cmem_malloc(sizeof(int) * n);

  // Reset the file and start populating numconn_array
  fseek(file, 0, SEEK_SET);
  int i, j, node, conn, line_count;
  char line[LINE_LENGTH];

  int **connections_array2;
  connections_array2 = *connections_array;
  int *numconn_array2;
  numconn_array2 = *numconn_array;
  int linecount_array[n];

  // Initialize numconn_array to all 0's
  for (i = 0; i < n; i++){
    numconn_array2[i] = 0;
  }

  // Handle -1's
  for (i = 0; i < n; i++) {
    memset(line, 0, LINE_LENGTH);
    fgets(line, LINE_LENGTH, file);
    
    sscanf(line, "%d %d", &node, &conn);
    if (conn == -1) {
      // before node
      for (j = 0; j < node; j++) {
	if (numconn_array2[j] < n-1) {
	  numconn_array2[j]++;
	}
      }

      // node
      numconn_array2[node] = n - 1;
      connections_array2[node] = tmc_cmem_malloc(sizeof(int) * (n - 1));

      linecount_array[node] = 1;
    }
  }

  fseek(file, 0, SEEK_SET);

  // Handle non -1's
  for (i = 0; i < n; i++) {
    // Grab the line 
    memset(line, 0, LINE_LENGTH);
    fgets(line, LINE_LENGTH, file);
    line_count = 0;
    for (j = 0; j < strlen(line); j++) {
      if (line[j] == ' ') {
	line_count++;
      }
    }
    line_count -= 2;

    sscanf(line, "%d %d", &node, &conn);
    if (conn != -1) {
      fseek(file, -strlen(line), SEEK_CUR);

      // Grab the first element (the node number)
      fscanf(file, "%d", &node);

      // Allocate and populate the row.
      linecount_array[node] = max(0, line_count);
      numconn_array2[node] += max(0, line_count);
      connections_array2[node] = tmc_cmem_malloc(sizeof(int) * numconn_array2[node]);

      for (j = 0; j < line_count; j++) {
	fscanf(file, "%d", &conn);
	numconn_array2[conn]++;
      }
    }
    // Eat up the rest of the line.
    fgets(line, LINE_LENGTH, file);
  }

  // Reset the file and start populating connections_array
  fseek(file, 0, SEEK_SET);

  int connindex_array[n];
  for (i = 0; i < n; i++){
    connindex_array[i] = 0;
  }

  int k;
  for (i = 0; i < n; i++) {
    // Grab the first element (the node number)
    fscanf(file, "%d", &node);

    for (j = 0; j < linecount_array[node]; j++) {
      fscanf(file, "%d", &conn);
      // add the conn to the node's array
      if (conn == -1) {
	for (k = 0; k < node; k++) {
	  connections_array2[node][connindex_array[node]] = k;
	  connindex_array[node]++;
	  // add the node to the conn's array
	  connections_array2[k][connindex_array[k]] = node;
	  connindex_array[k]++;
	}
      }
      else {
	connections_array2[node][connindex_array[node]] = conn;
	connindex_array[node]++;
	// add the node to the conn's array
	connections_array2[conn][connindex_array[conn]] = node;
	connindex_array[conn]++;
      }
    }

    // Eat up the rest of the line.
    fgets(line, LINE_LENGTH, file);
  }

  fclose(file);
  return 0;
}
